package com.hz.tgb.common;

import java.util.Arrays;

/**
 * byte转字符串相关工具类
 *
 * @author hezhao
 */
public class ByteUtil {

    private static final String HEX_DIGITS_STR = "0123456789ABCDEF";
    private static final char[] HEX_DIGITS_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    private static final String[] HEX_DIGITS_STRS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    private ByteUtil() {
        // 私有类构造方法
    }

    /***
     * byte数组转换为16进制字符串
     *
     * @param bytes
     * @return
     */
    public static String bytesToHexString(byte[] bytes) {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }

        // 方法1
        int l = bytes.length;
        char[] chars = new char[l * 2];
        int k = 0;
        for (int i = 0; i < l; i++) {
            chars[k++] = HEX_DIGITS_CHARS[bytes[i] >>> 4 & 0xf];
            chars[k++] = HEX_DIGITS_CHARS[bytes[i] & 0xf];
        }
        return new String(chars);

        // 方法2
//        StringBuffer sb = new StringBuffer();
//        int n;
//        for (int i = 0; i < bytes.length; i++) {
//            n = bytes[i];
//            if (n < 0) {
//                n += 256;
//            }
//            sb.append(HEX_DIGITS_STRS[n / 16]).append(HEX_DIGITS_STRS[n % 16]);
//        }
//        return sb.toString();

        // 方法3
//        StringBuilder sb = new StringBuilder();
//        int v;
//        String hv;
//        for (int i = 0; i < bytes.length; i++) {
//            v = bytes[i] & 0xFF;
//            hv = Integer.toHexString(v);
//            if (hv.length() < 2) {
//                sb.append(0);
//            }
//            sb.append(hv);
//        }
//        return sb.toString().toUpperCase();
    }

    /***
     * 16进制字符串转换为byte数组,注意输入字符串要大写
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || "".equals(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) HEX_DIGITS_STR.indexOf(c);
    }

    /**
     * Long转换成Byte数组
     * @param l
     * @return
     */
    public static byte[] toByteArray(Long l) {
        byte[] b = new byte[8];

        for (int i = 0; i < b.length; ++i) {
            b[7 - i] = (byte) ((int) (l >>> i * 8));
        }

        return b;
    }

    /**
     * Integer转换成Byte数组
     * @param i
     * @return
     */
    public static byte[] toByteArray(Integer i) {
        byte[] b = new byte[4];

        for (int j = 0; j < 4; ++j) {
            b[3 - j] = (byte) (i >>> j * 8);
        }

        return b;
    }


    public static void main(String[] args) throws Exception {
        byte[] bytes = "测试".getBytes("utf-8");
        System.out.println("字节数组为：" + Arrays.toString(bytes));
        String str = bytesToHexString(bytes);
        System.out.println("to 16进制字符串：" + str);

        System.out.println("==================================");

        byte[] bytes1 = hexStringToBytes(str);
        System.out.println("转换后的字节数组：" + Arrays.toString(bytes1));
        System.out.println(new String(bytes1, "utf-8"));


        System.out.println("==================================");
        System.out.println(new String(toByteArray(69L), "utf-8"));
        System.out.println(new String(toByteArray(69), "utf-8"));


        System.out.println("==================================");
        long startTime = System.currentTimeMillis();
        System.out.println("开始测试字节数组转16进制效率 >>>>>>>>> " + startTime);
        String str1;
        for (int i = 0; i < 10000000; i++) {
            str1 = bytesToHexString(bytes);
            // System.out.println("to 16进制字符串：" + str1);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("测试字节数组转16进制效率 >>>>>>>>> " + endTime + "， 共耗时" + (endTime - startTime) + "毫秒");
    }
}
